package dao;

import beans.Matiere;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import beans.Utilisateur;
import static dao.DAOUtilitaire.*;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author florianpf
 */
public class UtilisateurDAOImpl implements UtilisateurDAO{
    
    private DAOFactory  daoFactory;
       
    private static final String SQL_SELECT_PAR_EMAIL = "SELECT id_utilisateur, email, mot_de_passe, nom, prenom, type_utilisateur, date_inscription FROM utilisateur WHERE email = ?";
    private static final String SQL_INSERT = "INSERT INTO utilisateur (email, mot_de_passe, nom, prenom, type_utilisateur, date_inscription) VALUES (?, ?, ?, ?, ?, NOW())";
    private static final String SQL_SELECT_PAR_TYPE = "SELECT * FROM utilisateur WHERE type_utilisateur =?";
    private static final String SQL_SELECT_PAR_ID = "SELECT id_utilisateur, email, mot_de_passe, nom, prenom, type_utilisateur, date_inscription FROM utilisateur WHERE id_utilisateur = ? ";
    private static final String SQL_SELECT_PAR_IDPROMO = "SELECT id_utilisateur, email, mot_de_passe, nom, prenom, type_utilisateur, date_inscription FROM utilisateur u, affecte_promo_utilisateur a WHERE a.promotion = ? AND a.utilisateur=u.id_utilisateur AND u.type_utilisateur=0 ";
        
    public UtilisateurDAOImpl(DAOFactory daoFactory) {
         this.daoFactory = daoFactory;
    }
    
 /**
 * Simple méthode utilitaire permettant de faire la correspondance (le
 * mapping) entre une ligne issue de la table des utilisateurs (un
 * ResultSet) et un bean Utilisateur.
 */
    private static Utilisateur map( ResultSet resultSet ) throws SQLException {
        Utilisateur utilisateur = new Utilisateur();
        utilisateur.setId( resultSet.getInt("id_utilisateur"));
        utilisateur.setEmail( resultSet.getString("email"));
        utilisateur.setMotDePasse( resultSet.getString("mot_de_passe" ) );
        utilisateur.setNom( resultSet.getString( "nom" ) );
        utilisateur.setPrenom(resultSet.getString("prenom"));
        utilisateur.setType(resultSet.getInt("type_utilisateur"));
        utilisateur.setDateInscription( resultSet.getTimestamp( "date_inscription" ) );
        return utilisateur;
    }  


    @Override
    public void creerUtilisateur(Utilisateur utilisateur) throws IllegalArgumentException, DAOException {
        
        Connection connexion = null;
        PreparedStatement preparedStatement = null;
        ResultSet valeursAutoGenerees = null;

        try {
            /* Récupération d'une connexion depuis la Factory */
            connexion = daoFactory.getConnection();
            preparedStatement = initialisationRequetePreparee( connexion, SQL_INSERT, true, utilisateur.getEmail(), utilisateur.getMotDePasse(), utilisateur.getNom(), utilisateur.getPrenom(),  utilisateur.getType());
            int statut = preparedStatement.executeUpdate();
            /* Analyse du statut retourné par la requête d'insertion */
            if ( statut == 0 ) {
                throw new DAOException( "Échec de la création de l'utilisateur, aucune ligne ajoutée dans la table." );
            }
            /* Récupération de l'id auto-généré par la requête d'insertion */
            valeursAutoGenerees = preparedStatement.getGeneratedKeys();
            if ( valeursAutoGenerees.next() ) {
                /* Puis initialisation de la propriété id du bean Utilisateur avec sa valeur */
                utilisateur.setId( valeursAutoGenerees.getInt( 1 ) );
            } else {
                throw new DAOException( "Échec de la création de l'utilisateur en base, aucun ID auto-généré retourné." );
            }
        } catch ( SQLException e ) {
            throw new DAOException( e );
        } finally {
            fermeturesSilencieuses( valeursAutoGenerees, preparedStatement, connexion );
        }
    }

    @Override
     /* Implémentation de la méthode définie dans l'interface UtilisateurDao */
    public Utilisateur trouverUtilisateur(String email) throws DAOException {  
        Connection connexion = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        Utilisateur utilisateur = null;

        try {
            /* Récupération d'une connexion depuis la Factory */
            connexion = daoFactory.getConnection();
            preparedStatement = initialisationRequetePreparee( connexion, SQL_SELECT_PAR_EMAIL, false, email );
            resultSet = preparedStatement.executeQuery();
            /* Parcours de la ligne de données de l'éventuel ResulSet retourné */
            if ( resultSet.next() ) {
                utilisateur = map(resultSet);
            }
        } catch ( SQLException e ) {
            throw new DAOException( e );
        } finally {
            fermeturesSilencieuses( resultSet, preparedStatement, connexion );
        }

        return utilisateur;
    }
    
public Utilisateur trouverUtilisateur(Integer id) throws DAOException {  
        Connection connexion = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        Utilisateur utilisateur = null;

        try {
            /* Récupération d'une connexion depuis la Factory */
            connexion = daoFactory.getConnection();
            preparedStatement = initialisationRequetePreparee( connexion, SQL_SELECT_PAR_ID, false, id );
            resultSet = preparedStatement.executeQuery();
            /* Parcours de la ligne de données de l'éventuel ResulSet retourné */
            if ( resultSet.next() ) {
                utilisateur = map(resultSet);
            }
        } catch ( SQLException e ) {
            throw new DAOException( e );
        } finally {
            fermeturesSilencieuses( resultSet, preparedStatement, connexion );
        }

        return utilisateur;
    }

    @Override
    public List<Utilisateur> trouverUtilisateursParPromotion(Integer id_promo)throws DAOException{
        Connection connexion = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        List<Utilisateur> utilisateurs= new ArrayList<Utilisateur>();

        try {
            /* Récupération d'une connexion depuis la Factory */
            connexion = daoFactory.getConnection();
            preparedStatement = initialisationRequetePreparee( connexion, SQL_SELECT_PAR_IDPROMO, false, id_promo );
            resultSet = preparedStatement.executeQuery();
            /* Parcours de la ligne de données de l'éventuel ResulSet retourné */
            while ( resultSet.next() ) {
                utilisateurs.add(map(resultSet));
            }
        } catch ( SQLException e ) {
            throw new DAOException( e );
        } finally {
            fermeturesSilencieuses( resultSet, preparedStatement, connexion );
        }

        return utilisateurs;
    }

    @Override
    public void supprimerUtilisateur(String email) throws DAOException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public List<Matiere> trouverMatieresUtilisateur(Utilisateur utilisateur) throws DAOException {
        return null;
    }
    
    @Override
     public List<Utilisateur> tousUtilisateursParType(Integer type) throws DAOException, DAOException{  
        Connection connexion = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        List<Utilisateur> util = new ArrayList<Utilisateur>();
        try {
            /* Récupération d'une connexion depuis la Factory */
            connexion = daoFactory.getConnection();
            preparedStatement = initialisationRequetePreparee( connexion, SQL_SELECT_PAR_TYPE, true, type);
            resultSet = preparedStatement.executeQuery();            

            while(resultSet.next()){
               util.add(map(resultSet));
            }
            return util;    
            
        } catch ( SQLException e ) {
            throw new DAOException( e );
        } finally {
            fermeturesSilencieuses( resultSet, preparedStatement, connexion );
        }
    }


  public static Utilisateur mapUtilisateur (ResultSet rs) throws SQLException{
      
      return map(rs);
      
  }


 
    
}
